#include "sync.h"
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <string.h>

typedef struct {
    int reader_count;
    sem_t mutex;
    sem_t wr_lock;
} FileLock;

#define SHM_NAME "/file_lock_shm"

static FileLock *lock_table = NULL;

void sync_init() {
    int size = sizeof(FileLock) * MAX_INODES;

    // 创建或打开共享内存
    int fd = shm_open(SHM_NAME, O_CREAT | O_RDWR, 0666);
    ftruncate(fd, size);

    // 映射到地址空间
    lock_table = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    close(fd);

    // 初始化信号量
    for (int i = 0; i < MAX_INODES; ++i) {
        lock_table[i].reader_count = 0;
        sem_init(&lock_table[i].mutex, 1, 1);     // pshared = 1: 进程共享
        sem_init(&lock_table[i].wr_lock, 1, 1);   // pshared = 1: 进程共享
    }
}

void lock_acquire_read(int inode_id) {
    FileLock *lock = &lock_table[inode_id];
    sem_wait(&lock->mutex);
    if (++lock->reader_count == 1)
        sem_wait(&lock->wr_lock);
    sem_post(&lock->mutex);
}

void lock_release_read(int inode_id) {
    FileLock *lock = &lock_table[inode_id];
    sem_wait(&lock->mutex);
    if (--lock->reader_count == 0)
        sem_post(&lock->wr_lock);
    sem_post(&lock->mutex);
}

void lock_acquire_write(int inode_id) {
    sem_wait(&lock_table[inode_id].wr_lock);
}

void lock_release_write(int inode_id) {
    sem_post(&lock_table[inode_id].wr_lock);
}
